﻿#region Usings

using System;
using System.Collections.Generic;

using Gonte.Reflection;
using Gonte.UI; 

#endregion

namespace Gonte.Wpf.Controls.ViewModel
{
    /// <summary>
    /// Provides information of the view model by using reflection
    /// </summary>
    public class ContentObjectViewModelInfo
        : ContentViewModelInfo
    {
        #region Methods

        internal ContentObjectViewModelInfo(Type type)
        {
            _type = type;
        }

        public static ItemViewModelInfo GetInfo(Type type)
        {
            ExceptionThrower.ThrowWhenNull("type", type);

            string viewModelInfoName = type.FullName;

            if (!_viewModelInfos.ContainsKey(viewModelInfoName))
            {
                ContentObjectViewModelInfo viewModelInfo = new ContentObjectViewModelInfo(type);
                viewModelInfo.Populate();
                AddViewModelInfo(viewModelInfoName, viewModelInfo);

                return viewModelInfo;
            }

            return _viewModelInfos[viewModelInfoName];
        }

        public ContentViewModelInfo GetFolderViewModelInfo(string childrenPropertyName)
        {
            return (ContentViewModelInfo)ContentViewModelInfo.GetInfo(string.Format("{0}.{1}", _type.FullName,  childrenPropertyName));
        }

        #endregion

        #region Properties

        public Type Type
        {
            get { return _type; }
        } 

        #endregion

        #region Overridables

        internal override void Populate()
        {
            UserInterfaceAttribute uiAttribute = CustomAttribute.GetCustomAttribute<UserInterfaceAttribute>(_type, false);
            ExceptionThrower.ThrowWhenNull("viewModelAttribute", uiAttribute);

            // Set the label
            LabelProperty = uiAttribute.LabelProperty;

            ExceptionThrower.ThrowWhenNullOrEmpty("viewModelAttribute.LabelProperty", LabelProperty);

            // Set the icons
            IconUri = uiAttribute.IconUri;
            CollapsedIconUri = uiAttribute.CollapsedIconUri;
            ExpandedIconUri = uiAttribute.ExpandedIconUri;
            EmptyIconUri = uiAttribute.EmptyIconUri;

            base.Populate(); // Updates the null icons to the default one

            // Set the children information
            UserInterfaceItemAttribute[] childrenAttributes = CustomAttribute.GetCustomAttributes<UserInterfaceItemAttribute>(_type, false);

            if (null != childrenAttributes)
            {
                if (childrenAttributes.Length > 1)
                {
                    CreateFolders = true;
                }

                List<string> childrenProperties = new List<string>();

                foreach (UserInterfaceItemAttribute childrenAttribute in childrenAttributes)
                {
                    if (childrenAttribute != null
                        && !string.IsNullOrEmpty(childrenAttribute.PropertyName))
                    {
                        childrenProperties.Add(childrenAttribute.PropertyName);

                        if (CreateFolders)
                        {
                            ContentViewModelInfo folderViewModelInfo = GetFolderViewModelInfo(childrenAttribute.PropertyName);
                        }     
                    }
                }

                ChildrenProperties = new string[childrenProperties.Count];
                childrenProperties.CopyTo(ChildrenProperties);
            }
        }

        #endregion

        public delegate void FolderViewModelInfoCreatedHandler(ContentViewModelInfo folderViewModelInfo, string childrenPropertyName);

        #region Fields

        /// <summary>
        /// The type of the object to create the view model from
        /// </summary>
        private readonly Type _type;

        /// <summary>
        /// The name of the object property that maps to the label
        /// </summary>
        public string LabelProperty;

        /// <summary>
        /// The name of the properties that map to children in the view model
        /// </summary>
        public string[] ChildrenProperties;

        #endregion
    }
}
